package com.polaris.live.utils

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.NinePatch
import android.graphics.Rect
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.NinePatchDrawable
import android.util.LruCache
import com.polaris.live.App
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.utils.file.FileUtils
import com.polaris.live.widget.bubble.DownLoadFileUtil
import com.polaris.live.widget.bubble.NinePatchChunk
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File

/**
 *
 * @author Created by 天晴 on 2024/7/26 15:51
 * @since 1.0.0
 **/
object NinePatchDrawableUtil {

    /**
     * 从3级缓存加载获取.9Drawable
     */
    fun getNinePatchDrawable(
        url: String?,
        mRect: Rect?,
        success: (npd: Drawable) -> Unit,
        error: (e: Exception) -> Unit,
    ) {
        if (url.isNullOrEmpty()) {
            error.invoke(Exception("url  is isNullOrEmpty"))
            return
        }
        val cacheBitmap = getNineBitMapCache(url)
        if (cacheBitmap != null) {
            getNinePatchDrawableByBitMap(cacheBitmap, mRect).let(success)
            return
        }
        val filePath = FileUtils.getFilePath(FileUtils.getBubbleFile(), url)
        if (File(filePath).exists()) {
            getNinePatchDrawableByBitMap(BitmapFactory.decodeFile(filePath), mRect).let(success)
        } else {
            GlobalScope.launch(CoroutineScopeManager.defaultDispatcher) {
                val netBitmap = getBitMapByNet(url)
                withContext(CoroutineScopeManager.mainDispatcher) {
                    netBitmap ?: run {
                        error.invoke(IllegalArgumentException("Bitmap is null"))
                        return@withContext
                    }
                    getNinePatchDrawableByBitMap(netBitmap, mRect).let(success)
                }
            }
        }
    }

    /**
     * 从缓存加载
     */
    private fun getNineBitMapCache(url: String): Bitmap? {
        return if (url.isEmpty()) {
            null
        } else {
            getCache(url)
        }
    }

    /**
     * 从网络加载
     */
    private suspend fun getBitMapByNet(url: String): Bitmap? {
        return DownLoadFileUtil.getNineBitMap(url)?.also {
            setCache(url, it)
        }
    }

    /**
     * Rect(2.autoDp, 0.autoDp, 2.autoDp, 0.autoDp)
     * 从bitmap加载NinePatchDrawable
     */
    private fun getNinePatchDrawableByBitMap(bitmap: Bitmap, rect: Rect?): Drawable {
        val chunk = bitmap.ninePatchChunk
        val finalRect = rect ?: NinePatchChunk.deserialize(chunk)?.mPaddings
        return if (finalRect != null && chunk != null && NinePatch.isNinePatchChunk(chunk)) {
            NinePatchDrawable(
                App.instance.resources,
                bitmap,
                chunk,
                finalRect,
                null
            )
        } else {
            // 如果不是 .9 图，返回原始 Bitmap 包装的 Drawable
            BitmapDrawable(App.instance.resources, bitmap)
        }
    }

    //设置10M缓存
    private val cache = object : LruCache<String, Bitmap>(10 * 1024 * 1024) {
        override fun sizeOf(key: String, value: Bitmap): Int {
            return value.byteCount
        }
    }

    @Synchronized
    fun getCache(key: String): Bitmap? {
        return cache[key]
    }

    @Synchronized
    fun setCache(key: String, value: Bitmap?) {
        cache.put(key, value)
    }

}